/*
 *   Copyright 2008 Marcos Silva Pereira
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 */
class ProfessorControllerTests extends GroovyTestCase {

    void test_should_save_professor_when_all_parameters_are_ok() {

        ProfessorController controller = new ProfessorController()

        controller.params.name  = 'The Professor'
        controller.params.email = 'professor@email.com'
        controller.params.site  = 'http://site.com'
        controller.params.phone = '6547-6547'

        controller.save()

        def professors = Professor.list(max:1, sort:'id', order:'desc')
        Professor professor = professors[0]

        assertEquals 'The Professor', professor.name
        assertEquals 'professor@email.com', professor.email
        assertEquals 'http://site.com', professor.site
        assertEquals '6547-6547', professor.phone
        
    }

    void test_shoud_not_save_with_empty_params() {

        ProfessorController controller = controller()
        controller.save()

        assertEquals '/professor/create', controller.modelAndView.viewName
    }

    void test_should_show_the_professor_with_id_1() {
        ProfessorController controller = controller(id:1)
        
        def model = controller.show()
        assertEquals 'Professor 1', model.professor.name
    }

    void test_show_should_redirect_to_list_when_there_is_no_professor_with_id() {

        ProfessorController controller = controller(id:-1)

        controller.show()

        def redirecUrl = controller.response.redirectedUrl
        assertTrue 'Must redirect to list action', redirecUrl.startsWith('/professor/list')
        assertNotNull controller.flash.message
    }


    void test_list_should_return_10_professors_by_default() {
        ProfessorController controller = controller()
        def model = controller.list()

        assertEquals 10, model.professorList.size()
    }

    void test_list_should_return_the_specified_number_of_professors() {

        ProfessorController controller = controller(max:5)
        def model = controller.list()

        assertEquals 5, model.professorList.size()
    }

    void test_list_should_return_10_professors_when_max_is_less_than_zero() {
        ProfessorController controller = controller(max:-1)
        def model = controller.list()
        assertEquals 10, model.professorList.size()
    }

    void test_create_should_give_me_an_empty_professor() {
        ProfessorController controller = controller()
        def model = controller.create()

        def professor = model.professor
        ['name', 'email', 'site', 'phone'].each { property ->
            assertNull "The ${property} should be empty", professor."${property}"
        }
    }

    void test_should_delete_professor_with_id_1_and_redirect_to_list() {

        def controller = controller(id:1)
        controller.delete()

        def redirecUrl = controller.response.redirectedUrl
        assertTrue 'Must redirect to list action', redirecUrl.startsWith('/professor/list')
        assertEquals 'Professor 1 deleted', controller.flash.message
    }

    void test_delete_should_redirect_to_list_when_there_is_no_professor_with_id() {

        def controller = controller(id:-1)
        controller.delete()

        def redirecUrl = controller.response.redirectedUrl
        assertTrue 'Must redirect to list action', redirecUrl.startsWith('/professor/list')
        assertNotNull controller.flash.message
    }

    void test_should_raise_an_error_when_try_deleting_without_id() {
        shouldFail(NullPointerException) {
            def controller = controller()
            controller.delete()
        }
    }

    void test_should_return_professor_for_edition_when_passing_the_right_id() {
        def model = controller(id:1).edit()
        assertNotNull model.professor
        assertEquals 1, model.professor.id
    }

    void test_should_redirect_to_list_when_trying_edit_a_professor_that_no_exists() {
        def controller = controller(id:-1)
        controller.edit()

        def redirecUrl = controller.response.redirectedUrl
        assertTrue 'Must redirect to list action', redirecUrl.startsWith('/professor/list')
        assertEquals 'Professor not found with id -1', controller.flash.message

    }

    void test_should_update_a_professor_when_passing_all_params_ok() {

        def controller = controller(id:1, name:'New Name', email:'new@email.com', site:'http://new.site.com', phone:'9999-9999')
        controller.update()

        Professor professor = Professor.get(1)
        
        assertEquals 'New Name', professor.name
        assertEquals 'new@email.com', professor.email
        assertEquals 'http://new.site.com', professor.site
        assertEquals '9999-9999', professor.phone
        
    }

    void test_should_not_update_a_professor_when_passing_invalid_params() {
        def controller = controller(id:1)
        controller.update()

        Professor professor = Professor.get(1)
        ['name', 'email', 'site', 'phone'].each { property ->
            assertNotNull "$property could not be null", professor."$property"
        }
    }

    void test_should_redirect_to_list_when_trying_update_a_professor_that_no_exists() {

        def controller = controller(id:-1)
        controller.update()

        def redirecUrl = controller.response.redirectedUrl
        assertTrue 'Must redirect to edit action', redirecUrl.startsWith('/professor/edit')
        assertEquals 'Professor not found with id -1', controller.flash.message

    }

    void test_should_work_when_passing_max_as_a_string() {
        
        def controller = controller(max:'10')
        def model = controller.list()

        assertEquals 10, model.professorList.size()
    }

    def controller() {
        return controller([:])
    }

    def controller(params) {
        ProfessorController controller = new ProfessorController()
        params.each { key, value ->
            controller.params[key] = value
        }
        return controller
    }
}
